<!DOCTYPE html>
<html>
<head>
    <title>hakaton</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>

    <style type="text/css">
        div.sprite {
            width: 200px;
            height: 20px;
            border: solid 3px black;
            position: absolute;
            left: 0;
            top: 0;
            text-align: center;
            background-color: #abc;

        }
    </style>

    <script type="text/javascript">
        var sampleTags = ["apple", "raspberry", "blackberry", "pine", "pear", "currant", "pineapple", "mango", "cherry"];

        var curSuggestions = new Array();

        var array = null;
        var running = false;

        function go(suggestions) {
            array = suggestions;
            if (!running) {
                running = true;
                var result;
                while (array != null) {
                    a = array;
                    array = null;
                    result = mergeSuggestions(a);
                }
                curSuggestions = updateSuggestions(result)
                running = false;
            }
        }

        function mergeSuggestions(newSuggs) {
            var newSuggestions = new Array();
            var idx = 0, i;

            // removal of duplicated elements
            for (i = 0; i < newSuggs.length; i++) {
                if (newSuggs[i].findIn(newSuggestions) == null) {
                    newSuggestions[idx++] = newSuggs[i];
                }
            }

            // merging incoming suggestions with current ones
            var mergedSuggestions = new Array();
            idx = 0;
            var sugg;
            for (i = 0; i < newSuggestions.length; i++) {
                var curSugg = newSuggestions[i].findIn(curSuggestions);
                if (curSugg == null || curSugg.removed) {
                    sugg = new Suggestion(newSuggestions[i].tag, null, i);
                    mergedSuggestions[idx++] = sugg;
                } else {
                    sugg = new Suggestion(curSugg.tag, curSugg.curPos, i);
                    mergedSuggestions[idx++] = sugg;
                }
            }

            for (i = 0; i < curSuggestions.length; i++) {
                if (curSuggestions[i].removed) continue;
                var newSugg = curSuggestions[i].findIn(newSuggestions);
                if (newSugg == null) {
                    sugg = new Suggestion(curSuggestions[i].tag, curSuggestions[i].curPos, null);
                    mergedSuggestions[idx++] = sugg;
                }
            }

            return mergedSuggestions;
        }


        function updateSuggestions(curSuggestions) {

            var i, sugg;
            for (i = 0; i < curSuggestions.length; i++) {
                sugg = curSuggestions[i];
                if (sugg.newPos != null) {
                    if (sugg.curPos == null) {
                        addNewSprite(sugg);
                    } else {
                        moveInToList(sugg);
                    }
                } else {
                    break;
                }
            }

            var dropBound = i;

            for (; i < curSuggestions.length; i++) {
                sugg = curSuggestions[i];
                moveOutFromList(sugg);
            }

            return curSuggestions;
        }

        function Suggestion(tag, curPos, newPos) {
            this.tag = tag;
            this.curPos = curPos;
            this.newPos = newPos;
            this.removed = false;

            this.findIn = function(suggestions) {
                for (var i = 0; i < suggestions.length; i++) {
                    if (suggestions[i].tag == this.tag && !suggestions[i].removed)
                        return suggestions[i];
                }

                return null;
            };

            this.toString = function() {
                return "Suggestion(tag=" + this.tag + ", curPos=" + this.curPos + ", newPos=" + this.newPos + ", removed=" + this.removed + ");"
            }
        }


        function printSuggestions(suggestions) {
            for (var i = 0; i < suggestions.length; i++) {
                putLine(suggestions[i].toString());
            }
        }

        function sugTest() {
            var suggs = new Array();

            for (var i = 0; i < 5; i++) {
                suggs[i] = new Suggestion(sampleTags[Math.round(Math.random() * sampleTags.length) % sampleTags.length], null, i);
            }

            go(suggs);

        }

        function addNewSprite(sugg) {
            var panel = document.getElementById("spritePanel");

            if (document.getElementById("sprite-" + sugg.tag) == null) {
                var sprite = document.createElement("div");
                sprite.setAttribute("id", "sprite-" + sugg.tag);
                sprite.setAttribute("class", "sprite");
                sprite.setAttribute("style", "-webkit-transform: translate3d(500px, 400px, 50px) rotateY(80deg) ; -webkit-transition: -webkit-transform 500ms ease-in-out; -webkit-transform-style: preserve-3d;");
                sprite.appendChild(document.createTextNode(sugg.tag));
                panel.appendChild(sprite);
                setTimeout(function() {
                    moveInToList(sugg);
                }, 100);
            }

        }

        function moveInToList(sugg) {
            if (sugg.newPos != null) {
                var sprite = document.getElementById("sprite-" + sugg.tag);
                if (sprite != null) {
                    sprite.addEventListener("webkitTransitionEnd", function() {
                        sugg.curPos = sugg.newPos;
                    }, false);

                    sprite.style.webkitTransition = "-webkit-transform 500ms ease-in-out";
                    sprite.style.webkitTransform = "rotateY(0) translate3d(300px, " + (sugg.newPos * 50) + "px, -50px)";
                }
            }
        }

        function dropSprite(sprite) {
            var panel = document.getElementById("spritePanel");
            try {
                panel.removeChild(sprite);
            } catch (e) {

            }
        }

        function moveOutFromList(sugg) {
            if (sugg.newPos == null) {
                var sprite = document.getElementById("sprite-" + sugg.tag);
                if (sprite != null) {
                    sprite.addEventListener("webkitTransitionEnd", function() {
                        sugg.removed = true;
                        dropSprite(sprite);
                    }, false);

                    sprite.style.webkitTransform = "translate3d(100px, 400px, 50px) rotateY(-60deg)";
                    sprite.style.webkitTransition = "-webkit-transform 500ms ease-in-out"
                }
            }
        }

    </script>

    <script type="text/javascript">

        var html5rocks = {};
        html5rocks.webdb = {};

        html5rocks.webdb.db = null;

        html5rocks.webdb.open = function() {
            var dbSize = 10 * 1024 * 1024; // 10MB
            html5rocks.webdb.db = openDatabase('Tags', '1.0', 'Tags manager', dbSize);
        };

        html5rocks.webdb.onError = function(tx, e) {
        };

        html5rocks.webdb.onSuccess = function(tx, r) {
        };

        html5rocks.webdb.createTable = function() {
            html5rocks.webdb.db.transaction(function(tx) {
                tx.executeSql('CREATE TABLE IF NOT EXISTS ' +
                        'tags(ID INTEGER PRIMARY KEY ASC, tag TEXT UNIQUE, rank INTEGER, added_on DATETIME)', []);
            });
        };

        html5rocks.webdb.addTag = function(tagText) {
            html5rocks.webdb.db.transaction(function(tx) {
                var addedOn = new Date();
                tx.executeSql('INSERT INTO tags(tag, rank, added_on) VALUES (?, ?, ?)',
                        [tagText, 0, addedOn],
                        html5rocks.webdb.onSuccess,
                        html5rocks.webdb.onError);
            });
        };

        html5rocks.webdb.getAllTagItems = function(renderFunc, pattern) {
            html5rocks.webdb.db.transaction(function(tx) {
                tx.executeSql('SELECT id, tag, rank, added_on, length(tag) as le FROM tags where tag like ? order by le, tag', [ '%' + pattern + '%'], renderFunc, html5rocks.webdb.onError);
            });
        };

        function drawTagItems(tx, rs) {
            var rowOutput = "";
            for (var i = 0; i < rs.rows.length; i++) {
                rowOutput += renderTagItem(rs.rows.item(i));
            }
            var tagItems = document.getElementById('tagItems');
            tagItems.innerHTML = rowOutput;
        }

        function renderTagItem(row) {
            return '<li>' + row.tag + '</li>';
        }

        html5rocks.webdb.deleteTags = function() {
            html5rocks.webdb.db.transaction(function(tx) {
                tx.executeSql('DELETE FROM tags', [],
                        drawTagItems, html5rocks.webdb.onError);
            });
        };


        function loadTags() {

            var src = document.getElementById('srctxt');
            var srcTxt = src.value;
            var tags = srcTxt.split(" ");

            for (i = 0; i < tags.length; i++) {
                html5rocks.webdb.addTag(tags[i].trim().toLowerCase());
            }
            src.value = ""
        }


        function findTags() {
            var tp = document.getElementById("tagpattern").value
            html5rocks.webdb.getAllTagItems(feedAnimation, tp.trim().toLowerCase());
        }


        var currentTags = new Array();

        function feedAnimation(tx, rs) {
            //todo przekazanie animacji
            var tags = rs.rows;

            var t = new Array();
            for (var i=0; i<tags.length; i++) {
                t[i] = new Suggestion(tags.item(i).tag, null, i);
                if (i > 7) break;
            }
            currentTags = t;

        }

        function clearDB() {
            html5rocks.webdb.deleteTags()
        }

        function init() {
            html5rocks.webdb.open();
            html5rocks.webdb.createTable();


            setInterval(function() {
                go(currentTags);
            }, 700);
        }


    </script>
</head>


<body onload="init()">

<div>

    <div id="dbLoadingPanel" style="text-align:center;">
        <textarea id="srctxt" style="width:100%" rows="10"
                  placeholder="paste text here and upload it to start search"></textarea>
        <input type="button" value="upload" onclick="loadTags()"/>
        <input type="button" value="clear db" onclick="clearDB()"/>
    </div>


    <div style="padding-top:50px; text-align:center;">
        <input type="text" id="tagpattern" name="tagpattern" placeholder="type tag name.." style="width: 200px;"
               onkeyup="findTags()"/>
    </div>

    <div style="margin-left:50%;">
        <div id="spritePanel" style="-webkit-perspective: 800; perspective: 800; width: 800px; margin-left: -400px; margin-top: 100px; border: 1px solid black; height: 50%; -webkit-transform-style: preserve-3d;">
        </div>

    </div>

</div>
</body>
</html>
